<template>
 <div class="validate-input-container pb-3">
     <input 
        v-if="tag !== 'textarea'"
        class="form-control"
        :class="{'is-invalid':inputRef.error}"
        :value="inputRef.val"
        @input="updateValue"
        @blur="validateInput"
        v-bind="$attrs"
        > 
        <textarea
            v-else
            class="form-control"
            :class="{'is-invalid':inputRef.error}"
            :value="inputRef.val"
            @input="updateValue"
            @blur="validateInput"
            v-bind="$attrs"
        >
        </textarea>
        <div class='invalid-feedback' v-if="inputRef.error">{{inputRef.message}}</div>
 </div>
</template>

<script lang='ts'>
/* 新增注册的校验规则 */
import {defineComponent,PropType,reactive,onMounted,watch} from 'vue'
import {emitter} from '../ValidateForm/ValidateForm.vue'
interface emailProps {
    type: 'required' | 'email' | 'custom' | 'passwordLen',
    message: string,
    validator?: () => boolean
}
export type TagType = 'input' | 'textarea'

export type RuleProps = emailProps[]
export default defineComponent({
    props: {
        rules: Array as PropType<RuleProps>,
        modelValue: String, // 支持双向绑定
        tag: String as PropType<TagType>
    },
    inheritAttrs: false, //禁用 Attribute 继承
    setup(props,context) {
        const emailReg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
        const inputRef = reactive({
            val: props.modelValue ||'',
            error: false,
            message: ''
        })

        watch(()=> props.modelValue,(newVal) => {
            if (newVal) {
                inputRef.val = newVal || ''
            }
        })

        const validateInput = ()=> {
            if(props.rules) {
             
                const allPassed = props.rules.every(rule => {
                    let passed = true;
                    inputRef.message = rule.message
                    switch (rule.type) {
                        case 'required':
                           passed = inputRef.val.trim() != ''
                            break;

                        case 'email':
                            passed = emailReg.test(inputRef.val)
                            break;
                        case 'passwordLen':
                            passed = inputRef.val.trim().length >= 6
                            break
                        case 'custom':
                            passed = rule.validator ? rule.validator() : true
                            break;
                        default:
                            break;
                    }
                    return passed
                })
                inputRef.error = !allPassed
                return allPassed
            }
            return true
        }
        const updateValue = (e:KeyboardEvent) => {
            let targetValue = (e.target as HTMLInputElement).value
            inputRef.val = targetValue
            context.emit('update:modelValue',targetValue)
        }

        onMounted(() => {
            emitter.emit('form-item-created',validateInput)
        })
       
        return {
           inputRef,
           validateInput,
           updateValue
        }
    }
})
</script>

<style>

</style>